/**
 * dled_ctl.h - 动态数码管控制库 (3461AS-1) - 头文件
 * by Nixsawe <ziming_cool@126.com>
 * 2021-11-12 ~ 2021-12-17
 * 
 * 为了更方便地使用 3461AS-1 数码管，特封装此库
 */

#ifndef __DLED_CTRL__
#define __DLED_CTRL__

#include<string.h>
#include<atmel/at89x52.h>

typedef unsigned char DLED_T;
#define DLED_T_(x) ((DLED_T)(x))

#define DLED_ABC(a,b,c,d,e,f,g,dp) DLED_BYTE_DP((!!(DLED_T_(a))) | (!!(DLED_T_(b)) << 1) | (!!(DLED_T_(c)) << 2) \
									| (!!(DLED_T_(d)) << 3) | (!!(DLED_T_(e)) << 4) \
									| (!!(DLED_T_(f)) << 5) | (!!(DLED_T_(g)) << 6), DLED_T_(dp))
#define DLED_BYTE_DP(byte,dp) (DLED_T_(byte) & 0x7f) | (DLED_T_(dp) << 7)

#define DLED_DIGIT_0 DLED_ABC(1, 1, 1, 1, 1, 1, 0, 0)
#define DLED_DIGIT_1 DLED_ABC(0, 1, 1, 0, 0, 0, 0, 0)
#define DLED_DIGIT_2 DLED_ABC(1, 1, 0, 1, 1, 0, 1, 0)
#define DLED_DIGIT_3 DLED_ABC(1, 1, 1, 1, 0, 0, 1, 0)
#define DLED_DIGIT_4 DLED_ABC(0, 1, 1, 0, 0, 1, 1, 0)
#define DLED_DIGIT_5 DLED_ABC(1, 0, 1, 1, 0, 1, 1, 0)
#define DLED_DIGIT_6 DLED_ABC(1, 0, 1, 1, 1, 1, 1, 0)
#define DLED_DIGIT_7 DLED_ABC(1, 1, 1, 0, 0, 0, 0, 0)
#define DLED_DIGIT_8 DLED_ABC(1, 1, 1, 1, 1, 1, 1, 0)
#define DLED_DIGIT_9 DLED_ABC(1, 1, 1, 1, 0, 1, 1, 0)
#define DLED_DIGIT_MINUS DLED_ABC(0, 0, 0, 0, 0, 0, 1, 0)

#define DLED_MIN(a,b) ((a)<(b)?(a):(b))

// 仅当对应的宏没有被定义时，才定义它
// 这样允许工程中替换引脚定义
// 定义数码管控制寄存器地址 (74HC245 译码器的输入端口)
#ifndef DLED_ADDR
# define DLED_ADDR P0
#endif

// 定义位选线寄存器地址
#ifndef DLED_PCTL_ADDR
# define DLED_PCTL_ADDR 0xA2
#endif

// 定义位选线地址 (74HC138 译码器的三个引脚)
#ifndef DLED_PCTL_A
# define DLED_PCTL_A P2_2
#endif
#ifndef DLED_PCTL_B
# define DLED_PCTL_B P2_3
#endif
#ifndef DLED_PCTL_C
# define DLED_PCTL_C P2_4
#endif

extern DLED_T dled_digit[10];
extern DLED_T dled_buffer[8];

void dledShowDP(DLED_T byte, DLED_T dp, DLED_T pos);
void dledShow(DLED_T byte, DLED_T pos);
void dledShowBytes(DLED_T * a, int start_pos, int length);
void dledShowDigits(DLED_T * a, int start_pos, int length);
void dledFormat(long number, DLED_T * a, int length);
void dledShowNumber(long number, int show_prefix);
void dledMakeBuffer(long number, int show_prefix);
void dledShowBuffer();
void dledSetAll();
void dledClear();

#endif	/* __DLED_CTRL__ */
